package com.lagou.util;

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.data.Stat;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ZkCuratorUtils {

    private static CuratorFramework client;

    public ZkCuratorUtils() {

        RetryPolicy exponentialBackoffRetry = new ExponentialBackoffRetry(1000, 3);
        client = CuratorFrameworkFactory.builder()
                .connectString("127.0.0.1:2181")
                .sessionTimeoutMs(30000)
                .connectionTimeoutMs(10000)
                .namespace("servers")
                .retryPolicy(exponentialBackoffRetry)
                .build();
        client.start();
        client.getChildren().usingWatcher(new CuratorWatcher() {
            @Override
            public void process(WatchedEvent watchedEvent) throws Exception {
                int intValue = watchedEvent.getState().getIntValue();
                System.out.println("ZkCuratorUtils usingWatcher: " + intValue);
            }
        });
    }

    public static void main(String[] args) throws Exception {

        ZkCuratorUtils curator = new ZkCuratorUtils();
        System.out.println(curator.getOneServer("/"));
    }

    public String createEphemeralNode(String path, String content) throws Exception {
        String result = "";
        if (content != null && !content.equals("")) {
            result = client.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL)
                    .forPath(path, content.getBytes());
        } else {
            result = client.create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.EPHEMERAL)
                    .forPath(path);
        }
        return result;
    }

    public String createNode(String path, String content) throws Exception {
        String result = "";
        if (content != null && !content.equals("")) {
            result = client.create().creatingParentsIfNeeded()
                    .forPath(path, content.getBytes());
        } else {
            result = client.create().creatingParentsIfNeeded()
                    .forPath(path);
        }
        return result;
    }

    public boolean writeData(String path, String content) throws Exception {

        Stat stat = client.setData().forPath(path, content.getBytes());
        return stat != null;
    }

    public String getData(String path) throws Exception {
        byte[] bytes = client.getData().forPath(path);
        return new String(bytes);
    }

    public List<String> getChildren(String path) throws Exception {
        return client.getChildren().forPath(path);
    }

    public ServerInfo getOneServer(String path) throws Exception {

        List<String> list = client.getChildren().forPath(path);
        ServerInfo serverInfo = new ServerInfo(Integer.MAX_VALUE);
        for (String serverPath : list) {
            String strDuration = new String(client.getData().forPath("/" + serverPath));
            String[] ss = serverPath.split(":");
            long duration = Long.valueOf(strDuration);
            if (duration >= 0 && duration < serverInfo.getDuration()) {
                serverInfo = new ServerInfo(ss[0], Integer.parseInt(ss[1]), duration);
            }
        }

        return serverInfo;
    }

    public void delete(String path) throws Exception {
        Map map = new HashMap();
        client.delete().deletingChildrenIfNeeded().forPath(path);
    }

    public boolean exists(String path) throws Exception {
        Stat stat = client.checkExists().forPath(path);
        return stat != null;
    }

}

